package com.waijiaojun.tpo.service;

import com.waijiaojun.tpo.rest.RestClientException;
import com.waijiaojun.tpo.rest.dto.BindSms;
import com.waijiaojun.tpo.rest.dto.Sms;
import com.waijiaojun.tpo.utils.SMSUtil;
import com.waijiaojun.tpo.utils.SmsCodeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

import com.waijiaojun.tpo.entity.PhoneCode;
import com.waijiaojun.tpo.repository.PhoneCodeDao;

@Component
public class PhoneCodeService {
    private static final Logger logger = LoggerFactory.getLogger(PhoneCodeService.class);

    @Autowired
    private PhoneCodeDao phoneCodeDao;

    public int insert(PhoneCode pojo) {
        return phoneCodeDao.insert(pojo);
    }

    public int insertSelective(PhoneCode pojo) {
        return phoneCodeDao.insertSelective(pojo);
    }

    public int insertList(List<PhoneCode> pojos) {
        return phoneCodeDao.insertList(pojos);
    }

    public int update(PhoneCode pojo) {
        return phoneCodeDao.update(pojo);
    }

    public void sendCode(Sms sms) {
        //重数据库查询未过期的验证码（验证码有效期时长为30分钟）
        // 同一个手机号每分钟只能发1条，只查询出1分钟之内的验证码，如果有结果就不发了
        PhoneCode phoneCode = phoneCodeDao.getByAreaAndPhone(sms.getArea(),sms.getPhone());
        // 如果没有发送过验证码，直接发送，并且保存到数据库
        String code = SmsCodeUtil.genSmsCode();
        String content = "【外教君】您的短信验证码为" + code + "（30分钟内有效）";
        if (phoneCode == null) {
            phoneCode = new PhoneCode();
            phoneCode.setCode(code);
            phoneCode.setPhone(sms.getPhone());
            phoneCode.setArea(sms.getArea());
            phoneCodeDao.insertSelective(phoneCode);
            SMSUtil.sendSms(sms, content);
        } else {
            // 检查周期是否超过1分钟
            if (isOutOfPeriod(phoneCode.getUpdate_date(), 60)) {
                // ok,超过60秒，可以发验证码
                // 检查验证码是否过期（有效期30分钟）
                if (isOutOfPeriod(phoneCode.getUpdate_date(), 60 * 30)) {
                    // 超过30分钟有效期，发送新的验证码，更新数据库
                    phoneCode.setCode(code);
                    phoneCode.setPhone(sms.getPhone());
                    phoneCode.setArea(sms.getArea());
                    phoneCode.setUpdate_date(null);// 更新时间由数据库自动更新
                    phoneCodeDao.update(phoneCode);
                    SMSUtil.sendSms(sms, content);
                } else {
                    // no,未超过30分钟，在有效期之内，发送原来的验证码，并且不用保存到数据库
                    String content2 = "【外教君】您的短信验证码为" + phoneCode.getCode() + "（30分钟内有效）";
                    SMSUtil.sendSms(sms, content2);
                }
            } else {
                // no,未超过60秒
                logger.info("未超过60秒，不发验证码");
                throw new RestClientException("发送过于频繁");
            }
        }
    }



    /**
     * 是否超出给定的时间间隔
     * @param date
     * @param period 周期，单位秒
     * @return
     */
    private boolean isOutOfPeriod(Date date, int period) {
        long now = System.currentTimeMillis();//当前系统的毫秒数
        long t = date.getTime();//给定时间的毫秒数
        long result = now - t - period * 1000;
        logger.info("周期检测结果(>0为超过给定周期" + period + ")：" + result);
        return result > 0;
    }

    public boolean validateCode(BindSms bindSms) {
        PhoneCode p = phoneCodeDao.getByAreaAndPhone(bindSms.getArea(),bindSms.getPhone());
        if(p==null){
            throw new RestClientException("手机号码错误");
        }
        if(isOutOfPeriod(p.getUpdate_date(),1800)){
            // 超过30分钟有效期，发送新的验证码，更新数据库
            throw new RestClientException("超出30分钟，验证码失效，请重新发送验证码");
        }
        return p.getCode().equalsIgnoreCase(bindSms.getCode().trim());
    }
}
